<!--
 * @Description  : 
 * @Version      : 1.0
 * @Author       : seraph
 * @Date         : 2024-12-26 12:19:10
 * @LastEditors  : seraph
 * @LastEditTime : 2025-01-17 12:14:07
-->
<template>
  <h3>可写计算属性</h3>
  <p>
    计算属性默认是只读的。当你尝试修改一个计算属性时，你会收到一个运行时警告。只在某些特殊场景中你可能才需要用到“可写”的属性，你可以通过同时提供
    getter 和 setter 来创建：
  </p>
  <pre><code class="javascript" v-html="highlighted1"></code></pre>
  <p>
    现在当你再运行 fullName.value = 'John Doe' 时，setter 会被调用而 firstName 和 lastName
    会随之更新。
  </p>
  <p>{{ fullName }}</p>
  <button @click="changeFullName">修改 FullName</button>
</template>

<script lang="ts" setup>
import { ref, reactive, nextTick, shallowRef, watch, computed } from 'vue'
import hljs from 'highlight.js' // 导入 Highlight.js
import javascript from 'highlight.js/lib/languages/javascript' // JavaScript 语言支持
import html from 'highlight.js/lib/languages/xml' // HTML 语言支持
import 'highlight.js/styles/atom-one-light.css' // 导入样式

hljs.registerLanguage('javascript', javascript)
hljs.registerLanguage('xml', html)

const rawCode1 = `
&lt;script setup>
import { ref, computed } from 'vue'

const firstName = ref('John')
const lastName = ref('Doe')

const fullName = computed({
  // getter
  get() {
    return firstName.value + ' ' + lastName.value
  },
  // setter
  set(newValue) {
    // 注意：我们这里使用的是解构赋值语法
    [firstName.value, lastName.value] = newValue.split(' ')
  }
})
&lt;/script>`

const highlighted1 = ref(
  hljs
    .highlight(rawCode1, {
      language: 'javascript',
    })
    .value.replace(/&amp;gt;/g, '&gt;')
    .replace(/&amp;lt;/g, '&lt;'),
)

const author = reactive({
  name: 'John Doe',
  firstName: 'John',
  lastName: 'Doe',
  books: ['Vue 2 - Advanced Guide', 'Vue 3 - Basic Guide', 'Vue 4 - The Mystery'],
})

const publishedBooksMessage = computed(() => {
  return author.books.length > 0 ? 'Yes' : 'No'
})

const fullName = computed({
  get() {
    return author.firstName + ' ' + author.lastName
  },
  set(newValue) {
    const names = newValue.split(' ')
    author.firstName = names[0]
    author.lastName = names[1]
  },
})

const changeFullName = () => {
  const newName = prompt('请输入全名:', author.name)
  if (newName !== null) {
    fullName.value = newName
  }
}
</script>

<style scoped>
p {
  font-size: 16px;
  padding: 2px;
  margin: 5px 0;
}

/* 设置预格式化文本的样式 */
pre {
  /* 背景色 */
  background-color: #f1ffed;
  /* 边框 */
  border: 1px solid #ccc;
  /* 缩小内边距 */
  padding: 5px 5px 5px 10px;
  /* 允许滚动 */
  overflow: auto;
  /* 可选：设置上下外边距 */
  margin: 0px 0;
  /* 允许换行 */
  /* normal: 连续的空白字符会被合并为一个空格。文本会在允许的断点处自动换行。
     nowrap：连续的空白字符会被合并为一个空格。文本不会自动换行，即使在允许的断点处也不会换行。
     pre：保留所有的空白字符（包括空格、制表符和换行符）。文本只会在遇到换行符或者 <br> 标签时换行。
     pre-wrap：保留所有的空白字符。文本会在遇到换行符、<br> 标签，或者达到容器边界时换行。
     pre-line：合并连续的空白字符为一个空格，但保留换行符。文本会在遇到换行符、<br> 标签，或者达到容器边界时换行。
   */
  white-space: pre-wrap;
  /* 行高 */
  line-height: 120%;
  /* 定义缩进 */
  tab-size: 4;
}

h3,
h4,
h5,
h6 {
  margin: 25px 0 10px 0;
  line-height: 100%;
}

.bolder {
  font-weight: bolder;
}

.red {
  color: red;
}

button {
  margin: 5px 5px 5px 10px;
  line-height: 150%;
  width: auto;
  padding: 0 10px;
}
</style>
